package com.work.demo.juctest;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.LockSupport;

/**
 * @ClassName : AtomicStampedReferenceTest
 * @Description : 解决CAS的ABA问题
 * @Author : LinYa
 * @Date: 2021/11/15  15:11
 */
@Slf4j
public class AtomicStampedReferenceTest {


	public static void main(String[] args) {
		AtomicStampedReference<Integer> reference = new AtomicStampedReference<>(1, 1);

		new Thread(() -> {
			int[] stampHolder = new int[1];
			int value = reference.get(stampHolder).intValue();
			int stamp = stampHolder[0];
			log.debug("Thread1 read value: " + value + ", stamp: " + stamp);

			//阻塞1s
			LockSupport.parkNanos(1000000000L);

			if (reference.compareAndSet(value, 3, stamp, stamp + 1)) {
				log.debug("Thread1 update from " + value + ", to 3");
			} else {
				log.debug("Thread1 update fail!");
			}


		}, "Thread1").start();

		new Thread(() -> {
			int[] stampHolder = new int[1];
			int value = reference.get(stampHolder).intValue();
			int stamp = stampHolder[0];
			log.debug("Thread2 read value: " + value + ", stamp: " + stamp);


			if (reference.compareAndSet(value, 2, stamp, stamp + 1)) {
				log.debug("Thread2 update from " + value + ", to 2");
				value = reference.get(stampHolder).intValue();
				stamp = stampHolder[0];
				log.debug("Thread2 read value: " + value + ", stamp: " + stamp);
				if (reference.compareAndSet(value, 1, stamp, stamp + 1)) {
					log.debug("Thread2 update from " + value + ", to 1");
				}
			} else {
				log.debug("Thread2 update fail!");
			}


		}, "Thread2").start();
	}


}
